﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JumpNFight.Simulation;
using Microsoft.Xna.Framework;
using XDL.Framework.Messaging;
using XDL.Framework;

namespace JumpNFight.Weapons
{
    abstract class BalisticWeaponBase :
        IEventDispatcherClient
    {
        static int m_ID = 5000;

        protected static int GetNextID()
        {
            return m_ID++;
        }

        /// <summary>
        /// Random number generator.
        /// </summary>
        protected readonly static Random Rnd = new Random();

        /// <summary>
        /// Returns whether weapon is active or not.
        /// </summary>
        /// <remarks>
        /// Useful to simulate a weapon that has a delay before being active (ex: grenade or land mine)
        /// </remarks>
        public virtual bool IsActive
        {
            get
            {
                return true;
            }
        }
        protected World World
        {
            get;
            private set;
        }

        public int OwnerID
        {
            get;
            private set;
        }

        public abstract Moveable Moveable
        {
            get;
        }

        public bool Discard
        {
            get;
            private set;
        }

        public bool HitWall
        {
            get;
            set;
        }

        public float Lifetime
        {
            get;
            set;
        }

        public BalisticWeaponBase(World world, int playerId, Vector2 position, Vector2 velocity)
        {
            this.World = world;
            this.OwnerID = playerId;
            this.Discard = false;
        }

        public void Kill()
        {
            Discard = true;
            GameServices.EventDispatcher.UnregisterClient(this);
        }

        public virtual void Update(GameTime gameTime)
        {
            float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
            Lifetime -= dt;
            // EOL?
            if (Lifetime < 0)
            {
                Kill();
                return;
            }

            if (this.World.IsOutside(new Rectangle((int)Moveable.X - Moveable.Width / 2, (int)Moveable.Y - Moveable.Width / 2, Moveable.Width, Moveable.Height)))
                Kill();
        }

        public int ID
        {
            get { return Moveable.OwnerID; }
        }
        
        public virtual bool ProcessEvent(GameTime gameTime, int msgId, EventArgs e)
        {
            switch (msgId)
            {
                case NPCBase.DieEvent:
                    Kill();
                    break;

                case World.HitBottomTileEvent:
                case World.HitLeftTileEvent:
                case World.HitTopTileEvent:
                case World.HitRightTileEvent:
                    HitWall = true;
                    break;
            }

            return true;
        }
    }
}
